﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Mail;
using System.Net;
using System.Configuration;

namespace SocialIn.Biz.Utils
{
    public sealed class SendMailProvider
    {
        /// <summary>
        /// smtp서버 주소 지정
        /// </summary>
        string _smtp_host;

        /// <summary>
        /// SMTP포트
        /// </summary>
        int _smtpport = 587;

        string _smtp_CredentialID;
        string _smtp_CredentialPassword;
        MailAddress _from;

        public SendMailProvider()
        {
            _smtp_CredentialID = ConfigurationManager.AppSettings[ConfigName.SMTP_CredentialID].ToString();
            _smtp_CredentialPassword = ConfigurationManager.AppSettings[ConfigName.SMTP_CredentialPassword].ToString();
            _smtp_host = ConfigurationManager.AppSettings[ConfigName.SMTP_HOST];

            // 관리자 정보 [Gmail SMTP사용으로 인해 무의미]
            _from = new MailAddress() { Email = "test@gmail.com", DisplayName = "SocialinMaster" };
        }

        /// <summary>
        /// 동기로 메일을 발송합니다. 
        /// </summary>
        /// <param name="sendmailinfo">발송 메일 정보</param>
        public void Send(SendMailInfo sendmailinfo)
        {
            this.Send(sendmailinfo, false);
        }

        /// <summary>
        /// 비동기로 메일으 발송합니다.
        /// </summary>
        /// <param name="sendmailinfo">발송 메일 정보</param>
        public void SendAsync(SendMailInfo sendmailinfo)
        {
            this.Send(sendmailinfo, true);
        }

        /// <summary>
        /// 메일 발송
        /// </summary>
        /// <param name="sendmailinfo">발송 메일 정보</param>
        /// <param name="isAsync">비동기 여부</param>
        private void Send(SendMailInfo sendmailinfo, bool isAsync)
        {
            // SmtpClient 변수 선언
            SmtpClient smtp = new SmtpClient(_smtp_host, _smtpport);

            // Gmail메일 ID/ Password 지정
            smtp.Credentials = new NetworkCredential(_smtp_CredentialID, _smtp_CredentialPassword);

            smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtp.EnableSsl = true;

            MailMessage message = CreateDefaulMailMessage(sendmailinfo);
            object userState = message;

            if (isAsync)
            {
                // 비동기 이벤트 
                smtp.SendCompleted += (sender, e) =>
                    {
                        // TODO : 기능 구현...
                        if (e.Error != null)
                            return;
                    };

                // 비동기 호출
                smtp.SendAsync(message, userState);
            }
            else// 동기 호출
                smtp.Send(message);
        }


        /// <summary>
        /// 기본적인 메일 메세지를 생성하여 반환합니다.
        /// </summary>
        /// <param name="from">발신자 이메일</param>
        /// <param name="to">수신자 이메일</param>
        /// <param name="subject">메일 제목</param>
        /// <param name="body">메일 본문</param>
        /// <returns>메일 메세지 객체</returns>
        private MailMessage CreateDefaulMailMessage(SendMailInfo sendMailinfo)
        {
            // 메일 메세지 객체 생성
            MailMessage message = new MailMessage();

            //// 보내는 사람
            message.From = _from.ConvertToBuiltInMailAddress();

            // 수신자 지정합니다.
            message.To.Add(sendMailinfo.To.ConvertToBuiltInMailAddress());

            // 제목 인코딩
            message.SubjectEncoding = System.Text.Encoding.UTF8;

            // 제목 
            message.Subject = sendMailinfo.Subject;

            // 본문 인코딩
            message.BodyEncoding = System.Text.Encoding.UTF8;
            // 본문
            message.Body = sendMailinfo.Content;

            // HTML 허용
            message.IsBodyHtml = true;

            message.Priority = MailPriority.Normal;
            return message;
        }
    }

    /// <summary>
    /// 메일 정보
    /// </summary>
    public class MailAddress
    {
        /// <summary>
        /// 메일주소를 지정/반환합니다.
        /// </summary>
        public string Email { get; set; }

        /// <summary>
        /// 이름을 지정/반환합니다.
        /// </summary>
        public string DisplayName { get; set; }

        public MailAddress()
        {
        }

        public MailAddress(string email, string displayName)
        {
            this.Email = email;
            this.DisplayName = displayName;
        }


        /// <summary>
        /// 빌트인 MailAddress 객체를 만들어 반환합니다.
        /// </summary>
        /// <returns></returns>
        public System.Net.Mail.MailAddress ConvertToBuiltInMailAddress()
        {
            return new System.Net.Mail.MailAddress(this.Email, this.DisplayName);
        }
    }

    /// <summary>
    /// 발송메일 내용정보
    /// </summary>
    public sealed class SendMailInfo
    {
        /// <summary>
        /// 보내는 사람의 메일 정보를 지정/반환합니다. 
        /// </summary>
        public MailAddress From { get; set; }

        /// <summary>
        /// 받는 사람의 메일 정보를 지정/반환합니다.
        /// </summary>
        public MailAddress To { get; set; }

        /// <summary>
        /// 제목을 지정/반환합니다.
        /// </summary>
        public string Subject { get; set; }

        /// <summary>
        /// 내용을 지정/반환합니다.
        /// </summary>
        public string Content { get; set; }

        /// <summary>
        /// 생성자
        /// </summary>
        public SendMailInfo()
        {
        }
    }
}
